﻿// 功能：
// 描述：
// 作者：温伟鹏
// 日期：2010/10/26 15:35:48

using System;
using System.Collections.Generic;
using System.Text;

namespace MeizuSDK.Drawing.OpenGLES
{
    /// <summary>
    /// OpenGL ES 设备类
    /// </summary>
    public class GLESDevice
    {
        private int major;
        private int minor;
        private bool destroyed;

        public EGLDisplay Display
        {
            get;
            set;
        }

        public EGLContext Context
        {
            get;
            set;
        }

        public EGLSurface Surface
        {
            get;
            set;
        }

        public int Major
        {
            get { return this.major; }
            set
            {
                if (value != this.major)
                    major = value;
            }
        }

        public int Minor
        {
            get { return this.minor; }
            set
            {
                if (value != this.minor)
                    minor = value;
            }
        }

        public bool Activated
        {
            get;
            set;
        }

        public GLESDevice()
        {
            Display = EGLDisplay.Null;
            Surface = EGLSurface.None;
            Context = EGLContext.None;

            Major = 0;
            Minor = 0;
        }

        #region 函数
        /// <summary>
        /// 初始化EGL设备
        /// </summary>
        /// <param name="hWindow">窗口句柄</param>
        /// <param name="fullScreen">是否全屏</param>
        /// <returns>返回true，表示初始化成功；否则表示初始化失败</returns>
        public bool InitDevice(IntPtr hWindow, bool fullScreen)
        {
            if (hWindow == IntPtr.Zero)
                return false;

            IntPtr hdcWindow = NativeMethods.GetDC(hWindow);

            Display = egl.GetDisplay(new EGLNativeDisplayType(hdcWindow));

            if (Display.Pointer == IntPtr.Zero)
                return false;

            if (!egl.Initialize(Display, out major, out minor))
                return false;

            EGLConfig[] configs = new EGLConfig[10];

            int[] cfg_attr_list = new int[] 
                { 
                    egl.EGL_RED_SIZE, 5, 
                    egl.EGL_GREEN_SIZE, 6, 
                    egl.EGL_BLUE_SIZE, 5, 
                    egl.EGL_DEPTH_SIZE, 16 , 
                    egl.EGL_SURFACE_TYPE, egl.EGL_WINDOW_BIT,
                    egl.EGL_STENCIL_SIZE, egl.EGL_DONT_CARE,
                    egl.EGL_NONE, egl.EGL_NONE 
                };

            int num = 0;

            if (!egl.ChooseConfig(Display, cfg_attr_list, configs, 1, out num))
                return false;

            if (num == 0)
                return false;

            EGLConfig config = configs[0];

            Surface = egl.CreateWindowSurface(Display, config, hWindow, null);

            if (Surface.Pointer == IntPtr.Zero)
                return false;

            Context = egl.CreateContext(Display, config, EGLContext.None, null);

            if (Context.Pointer == IntPtr.Zero)
                return false;

            if (!egl.MakeCurrent(Display, Surface, Surface, Context))
                return false;

            Activated = true;

            destroyed = false;

            return true;
        }

        /// <summary>
        /// 销毁设备
        /// </summary>
        public void DestroyDevice()
        {
            if (destroyed)
                return;

            if (!egl.DestroySurface(Display, Surface))
                throw new Exception("销毁Surface时发生错误！");

            if (!egl.DestroyContext(Display, Context))
                throw new Exception("销毁Context时发生错误！");

            if (!egl.Terminate(Display))
                throw new Exception("终止显示时发生错误！");

            destroyed = true;
        }
        #endregion
    }
}
